package org.jsola.hr.common.oneKeyPay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import lombok.extern.slf4j.Slf4j;
import org.jsola.exception.ParamException;
import org.jsola.hr.vo.payAli.BatchOrderVO;
import org.jsola.hr.vo.payAli.PayeeInfoVO;
import org.jsola.hr.vo.payAli.TransOrderVO;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 支付宝批量支付相关方法
 * @author wu
 */
@Slf4j
public class Alipay {

    //支付宝网关（固定）。
    public static final String URL = "https://openapi.alipay.com/gateway.do";
    //APPID 即创建小程序后生成。
    public static final String APPID = "2021002187615001";
    //开发者私钥，由开发者自己生成。
    public static final String APP_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjGuB8E12FZ7Ro+phLBosRiHuP87G7m4GIcX3iVWwH0tfPBjkV+tU4HR7pRAQZeNKKiAkU3q6Phi+zWLUAfE0aDias7ITmaARdGFq+4pVDdn3kPAY9K6mXVg6X+E10jHGZFwHzgy1cJj7XHW+jZhzPqNR3hw3XjWqF9ksrHM/AntA+tb0cqfawZ7EOnpgNsPysJSw62EE0iKqZh1O1M1qroksgrkj6XRTBBjGN3UuXEbMTrrex4ZpU83BoqI32q2noP1HDvjgVOgJ0534hlLcMOGKwhKy2OBd58RsCBgSBgQjsBI1bZuMwXc3oOE+rdElwot+63B60KFABUFZO4i15AgMBAAECggEAOlvOgHaJWsc9VOZ9ATMpJS/ZTitap46/bSt2aDo6Oh5lmyxV1ph2G+rHeZ0dfmOtqWV9Ilt+x9myTZBqyu6uw6jWi77g2nPTQ+AH8A6wa4AFEVmsvcxWlNB0zklIpW/u4WDLEO8ZlsQUbfGZVTSfEGoPA2luOXbe62mxgY6AgyF9NNda6qUBCVvZmqB/R85KpotuvFgCr78ClPD5S1nv8pEwMEdKIxUBdrpJeHT0IXV/WD9BHpN+q39g8mUB8bg2f9JRZ+GZ0L5g8mGQzgxnGEJbBem07t+Q0NYkladic7jji/YJXZCLN8x7+2YaZa3T01sLHyhhdW8QY+C0YgkyxQKBgQDbh6ozHG1VGZUsOaIngsLMN6eWFhl/9mTYGSGIpBXQn28YdoxUEcv7ysdBqxbcG+qngpamYCn8FPKHKKn1wrpa320wAiAl/F8f+KICm17XAjXWAQ/iWbf+DM15FGkvQWXrTpd5D0xCUVFyyFITLWs+eg+jWrN+nlhGhhr7rm3m+wKBgQC+M4dubH5mi1xDUqpBT6Sn/Y52K08oZGL247TSMTtJILkZ9B/8rXKv1MPiybGFvKkSjoAErca20GU26w7vHls888kApFZQhLzdkHlIeqhdCPqTq2XeQdtRHHMmTYK3t8nmHOxIwmIVpmbO6jUEkLkqkRmlAUKMFjMwoaLlPFujGwKBgQCYYbQnpDzUDFz6hMrk6CQ1QxCF4rMymqJnShJ32YX2+SRRc8B2fp/8GEZ1c7/7azlXqxLNTAT4oMW0Qeqv18opV9tfrqoIFAUnmRtD+fs7/aHG+ZfAA4zuwI5D1IIqthd73WLROmgxxGZn6VrnSuidRnbiagwcAOe/lEjYmLxazwKBgBgYEvnsCH8Y/FES8bpgSm11c0yI4/gr71VzNv7Bec8jtA8Tm9G4byTTARWDk1drtMdDAfiVwux5rbitQjEMWWZ5Q2cvaje8+OfgW1zRHO7cKlH2jmr/ULcPsY6SlxKK16qs00nMRfyUHcXsaVbwtmQsCWGbrUBtt4Jbl3UOllUtAoGAN+N79ABiNcOwW08iYxhqRcs4HwH1lmTL097ujmLi4YatZYPVTNFgxCBwMm4dVtCeo9jgUPQTJAxqzdiC+C8L/oBOB0dYlAR4VXx06w+F24zi2hvtVrU+Ojci8BJr5mHX3hu83kw7JWhpYOAi2oZpd3hA5sgEyAiGwUbFA9vCwAs=";
    //参数返回格式，只支持 JSON 格式。
//    public static final String FORMAT = "JSON";
    //编码集，支持 GBK/UTF-8。
//    public static final String CHARSET = "UTF-8";
    //商户生成签名字符串所使用的签名算法类型，目前支持 RSA2 和 RSA，推荐使用 RSA2。
//    public static final String SIGN_TYPE = "RSA2";
    public static final String APP_CERT_PATHAPP_CERT_PATH = "D:\\payAli\\appCertPublicKey_2021002187615001.crt";
    public static final String ALIPAY_CERT_PATH = "D:\\payAli\\alipayCertPublicKey_RSA2.crt";
    public static final String ALIPAY_ROOT_CERT_PATH = "D:\\payAli\\alipayRootCert.crt";

    public static void main(String[] args) throws AlipayApiException {

        // 公共参数
        CertAlipayRequest certAlipayRequest = buildCertAlipayRequest(URL, APPID, APP_PRIVATE_KEY,
                APP_CERT_PATHAPP_CERT_PATH, ALIPAY_CERT_PATH, ALIPAY_ROOT_CERT_PATH);

        //授权码转token
//        StringBuilder pid = new StringBuilder();
//        String appAuthToken = alipayOpenAuthTokenApp("745686e7f5824ae4846b5483b6178X32", certAlipayRequest, pid);
//        System.out.println("appAuthToken=========================");
//        System.out.println(appAuthToken);
//        System.out.println("pid==================================");
//        System.out.println(pid.toString());

//        String appAuthToken = "202111BBda066e044ae54d7899309686ae9d8X32";
        String appAuthToken = "202111BBf29ef75921b5485298ef0e4044a43X71";
        // 校验appAuthToken 是否有效
//        boolean isValid = selectAppAuthTokenStatus(appAuthToken, certAlipayRequest);
//        System.out.println(isValid);
//        // 创建批量付款单据
//        BatchOrderVO batchOrderVO = batchOrderVO();
//        String batchTransId = alipayFundBatchCreateRequest(batchOrderVO, appAuthToken, certAlipayRequest);
//        System.out.println("batchTransId=========================");
//        System.out.println(batchTransId);
//        if (batchTransId == null) {
//            return;
//        }
//        String batchTransId = "202110259243898565";
//        //支付批量转账单据
//        String url = alipayFundTransPagePay(batchTransId, "http://cczhixinren.cck51.cn/", appAuthToken, certAlipayRequest);
//        System.out.println("url=========================");
//        System.out.println(url);
//        System.out.println("url=========================");

        String batchTransId = "202112169342896593";
        // 移动支付
        String urlMove = alipayMovePay(batchTransId, appAuthToken, certAlipayRequest);
//        System.out.println("urlMove=========================");
//        System.out.println(urlMove);
//        System.out.println("urlMove=========================");
//

        //查询批次支付状态
//        alipaySelectStatus("2021101410442154whahy23", appAuthToken, certAlipayRequest);
    }

    public static CertAlipayRequest buildCertAlipayRequest(String url, String appId, String appPrivateKey,
                                                           String appCertPath, String alipayCertPath,
                                                           String alipayRootCertPath) {

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(url);
        certAlipayRequest.setAppId(appId);
        certAlipayRequest.setPrivateKey(appPrivateKey);
        certAlipayRequest.setFormat("JSON");
        certAlipayRequest.setCharset("UTF-8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(appCertPath);
        certAlipayRequest.setAlipayPublicCertPath(alipayCertPath);
        certAlipayRequest.setRootCertPath(alipayRootCertPath);
        return certAlipayRequest;
    }

    /**
     * 根据code获取商家的appAuthToken（appAuthToken批量转账操作需要该appAuthToken）
     * @param code 商家授权返回的code
     * @return appAuthToken
     */
    public static String alipayOpenAuthTokenApp(String code, CertAlipayRequest certAlipayRequest, StringBuilder pid) {
        try {
            DefaultAlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
            // 请求参数
            request.setBizContent("{\n" +
                    "\t\"grant_type\": \"authorization_code\",\n" +
                    "\t\"code\": \"" + code + "\"\n" +
                    "}");
            AlipayOpenAuthTokenAppResponse response = alipayClient.certificateExecute(request);
            log.info("调用支付宝获取商家appAuthToken 返回结果:{}", JSONObject.toJSONString(response));
            if (response.isSuccess()) {
                pid.append(response.getUserId());
                return response.getAppAuthToken();
            } else {
                return null;
            }
        } catch (Exception e) {
            log.error("调用遭遇异常，原因：" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 创建批量付款单据
     */
    public static String alipayFundBatchCreateRequest(BatchOrderVO batchOrderVO, String appAuthToken,
                                                      CertAlipayRequest certAlipayRequest) {
        try {
            DefaultAlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipayFundBatchCreateRequest request = new AlipayFundBatchCreateRequest();
            // 请求参数
            request.setBizContent(JSON.toJSONString(batchOrderVO));
            request.putOtherTextParam("app_auth_token", appAuthToken);

            AlipayFundBatchCreateResponse response = alipayClient.certificateExecute(request);
            log.info("批次id为：{}调用支付宝创建批量付款单据返回结果:{},=========batchOrderVO:{}",
                    batchOrderVO.getOutBatchNo(),
                    JSONObject.toJSONString(response),
                    JSONObject.toJSONString(batchOrderVO));
            if (response.isSuccess()) {
                return response.getBatchTransId();
            } else {
                log.error("批次id为：{}调用支付宝创建批量付款单据返回结果:{},=========batchOrderVO:{}",
                        batchOrderVO.getOutBatchNo(),
                        JSONObject.toJSONString(response),
                        JSONObject.toJSONString(batchOrderVO));
                return null;
            }
        } catch (Exception e) {
            log.error("调用支付宝创建批量付款单据遭遇异常，原因：{}", e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 支付批量转账单据
     */
    public static String alipayFundTransPagePay(String orderId, String returnUrl, String appAuthToken,
                                                CertAlipayRequest certAlipayRequest) {
        try {
            DefaultAlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipayFundTransPagePayRequest request = new AlipayFundTransPagePayRequest();
            // 请求参数
            request.setBizContent("{" +
                    "\"biz_scene\": \"MESSAGE_BATCH_PAY\"," +
                    "\"product_code\": \"BATCH_API_TO_ACC\"," +
                    "\"order_id\": \""+ orderId +"\"" +
                    "}");
            request.setReturnUrl(returnUrl);
            request.putOtherTextParam("app_auth_token", appAuthToken);

            AlipayFundTransPagePayResponse response = alipayClient.pageExecute(request, "get");
            log.info("调用支付宝支付批量转账单据返回结果:{}", JSONObject.toJSONString(response));
            if (response.isSuccess()) {
                return response.getBody();
            } else {
                log.error("调用支付宝批次PC支付接口返回结果:{}", JSONObject.toJSONString(response));
                throw new ParamException("调用支付宝批次PC支付接口失败! 失败原因：" + response.getSubMsg());
            }
        } catch (Exception e) {
            log.error("调用支付宝支付批量转账单据遭遇异常，原因：{}", e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 查询批次结果
     */
    public static AlipayFundBatchDetailQueryResponse alipaySelectStatus(String outBatchNo, String appAuthToken, CertAlipayRequest certAlipayRequest) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipayFundBatchDetailQueryRequest request = new AlipayFundBatchDetailQueryRequest();
            request.setBizContent("{" +
                    "\"biz_scene\":\"MESSAGE_BATCH_PAY\"," +
                    "\"product_code\":\"BATCH_API_TO_ACC\"," +
                    "\"out_batch_no\":\""+outBatchNo+"\"," +
                    "  }");
            request.putOtherTextParam("app_auth_token", appAuthToken);
            AlipayFundBatchDetailQueryResponse response = alipayClient.certificateExecute(request);
            log.info("调用支付宝查询批次结果返回结果:{}", JSONObject.toJSONString(response));
            if(response.isSuccess()){
                return response;
            } else {
                return null;
            }
        } catch (Exception e) {
            log.error("调用支付宝查询批次结果遭遇异常，原因：{}", e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 批次移动支付接口
     */
    public static String alipayMovePay(String batchTransId, String appAuthToken, CertAlipayRequest certAlipayRequest) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipayFundBatchAppPayRequest request = new AlipayFundBatchAppPayRequest();
            request.setBizContent("{" +
                    "\"batch_trans_id\":\""+batchTransId+"\"" +
                    "  }");
            request.putOtherTextParam("app_auth_token", appAuthToken);
            AlipayFundBatchAppPayResponse response = alipayClient.pageExecute(request, "get");

            String parmStr = "";
            if(response.isSuccess()){
                parmStr = response.getBody();
            } else {
                log.error("调用支付宝批次移动支付接口返回结果:{}", JSONObject.toJSONString(response));
                throw new ParamException("调用支付宝批次移动支付接口失败!");
            }
            // 初始支付参数
            String parm = parmStr.substring(parmStr.indexOf("?") + 1);
            log.info("调用支付宝批次移动支付接口初始参数:{}", parm);
            // 将支付参数整体 encode 一次
            String encodeParm = URLEncoder.encode(parm, "utf-8");
            // 拼接带参页面路径并再次整体encode
            String pageEncode = URLEncoder.encode("pages/confirm/index/index?signParams=" + encodeParm, "utf-8");
            // 拼接跳转支付宝内支付地址，如果商户无需回跳，参考这个
            String payUrl = "alipays://platformapi/startapp?appId=2021002133661287&appClearTop=false&startMultApp=YES"
                    + "&page=" + pageEncode;
            // 拼接完整跳转链接
            String fullUrl = "https://render.alipay.com/p/s/ulink/?scheme=" + URLEncoder.encode(payUrl, "utf-8");
            log.info("调用支付宝批次移动支付接口拼接的完整跳转链接:{}", fullUrl);
            return fullUrl;
        } catch (Exception e) {
            log.error("调用支付宝批次移动支付接口遭遇异常，原因：{}", e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 校验商户的token是否有效
     */
    public static boolean selectAppAuthTokenStatus(String appAuthToken, CertAlipayRequest certAlipayRequest) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipayOpenAuthTokenAppQueryRequest request = new AlipayOpenAuthTokenAppQueryRequest();
            request.setBizContent("{" +
                    "\"app_auth_token\":\"" + appAuthToken + "\"" +
                    "  }");
            AlipayOpenAuthTokenAppQueryResponse response = alipayClient.certificateExecute(request);
            return "valid".equals(response.getStatus());
        } catch (AlipayApiException e) {
            log.error("调用支付宝校验商户的token是否有效接口遭遇异常，原因：{}", e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
    }


    private static BatchOrderVO batchOrderVO() {
        //创建批量付款单据
        BatchOrderVO batchOrderVO = new BatchOrderVO();
        batchOrderVO.setOutBatchNo("2021101410442154whahy23");
        batchOrderVO.setProductCode("BATCH_API_TO_ACC");
        batchOrderVO.setBizScene("MESSAGE_BATCH_PAY");
        batchOrderVO.setOrderTitle("批量转账");
        batchOrderVO.setTotalTransAmount(1.01D);
        batchOrderVO.setTotalCount("1");
        batchOrderVO.setTimeExpire("2021-10-26 15:36");
        batchOrderVO.setRemark("批量转账的备注");
        batchOrderVO.setPassbackParams("{\"userId\":\"whahy\",\"userName\":\"wu\"}");
        List<TransOrderVO> transOrderListVOList = new ArrayList<>();
        // 第一个收款信息
        TransOrderVO transOrderC = new TransOrderVO();
        transOrderC.setOutBizNo("cc202110141057123456");
        transOrderC.setTransAmount("1.01");
        PayeeInfoVO payeeInfoC = new PayeeInfoVO();
        payeeInfoC.setIdentity("36197806@qq.com");
        payeeInfoC.setIdentityType("ALIPAY_LOGON_ID");
        payeeInfoC.setName("东东");
        transOrderC.setPayeeInfo(payeeInfoC);
        transOrderC.setOrderTitle("给蔡超的标题");
        transOrderC.setRemark("给蔡超的备注");
//        transOrderListVOList.add(transOrderC);
        // 第二个收款方
        TransOrderVO transOrderW = new TransOrderVO();
        transOrderW.setOutBizNo("wh202110141057123456");
        transOrderW.setTransAmount("1.01");
        PayeeInfoVO payeeInfoW = new PayeeInfoVO();
        payeeInfoW.setIdentity("2088422749207382");
        payeeInfoW.setIdentityType("ALIPAY_USER_ID");
        payeeInfoW.setName("吴鸿");
        transOrderW.setPayeeInfo(payeeInfoW);
        transOrderW.setOrderTitle("给吴鸿的标题");
        transOrderW.setRemark("给吴鸿的备注");
        transOrderListVOList.add(transOrderW);
        batchOrderVO.setTransOrderList(transOrderListVOList);
        return batchOrderVO;
    }

}
